package com.future.domain.DTO;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class PageDTO <T>{
    /**
     * 数据列表
     */
   private List<T> rows;
    /**
     * 总条数
     */
   private Long total;
    /**
     * 总页数
     */
   private Long totalPage;
    /**
     * 返回空分页结果
     * @param p MybatisPlus的分页结果
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> empty(Page<P> p){
        return new PageDTO<>(Collections.emptyList(), p.getTotal(), p.getPages());
    }



    /**
     * 将MybatisPlus分页结果转为 VO分页结果，使用BeanUtil.copyProperties进行属性拷贝
     * @param p MybatisPlus的分页结果
     * @param voClass 目标VO类型
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    //要求：Article 和 ArticleVO 的属性名一致（如 id、title 等），否则需要手动处理差异字段。
    public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据，返回空结果
            return empty(p);
        }
        // 2.数据转换
        List<V> vos = BeanUtil.copyToList(records, voClass);
        // 3.封装返回
        return new PageDTO<>( vos, p.getTotal(), p.getPages());
    }

    /**
     * 将MybatisPlus分页结果转为 VO分页结果，允许用户自定义PO到VO的转换方式
     * @param p MybatisPlus的分页结果
     * @param convertor PO到VO的转换函数
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    //自定义 PO 到 VO 的转换逻辑（当属性名不一致或需要复杂转换时使用）。
    public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据，返回空结果
            return empty(p);
        }
        // 2.数据转换1
        List<V> vos = records.stream().map(convertor).collect(Collectors.toList());
        // 3.封装返回
        return new PageDTO<>(vos, p.getTotal(), p.getPages());
    }


    /**
     * 将MyBatis-Plus的Page转换为自定义PageDTO
     */
    public static <T> PageDTO<T> pageConvert(Page<T> mpPage) {
        return new PageDTO<T>()
                .setRows(mpPage.getRecords())
                .setTotal(mpPage.getTotal())
                .setTotalPage(mpPage.getPages());
    }

}
